package com.pig4cloud.pig.iotData.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pig.duorou.dto.DuorouKgnpkDevDataInfoDto;
import com.pig4cloud.pig.iot.entity.IotDeviceMessageEntity;
import com.pig4cloud.pig.iot.service.IotDeviceMessageService;
import com.pig4cloud.pig.iotData.entity.AbnormalIndicator;
import com.pig4cloud.pig.iotData.entity.IotDataKgnpkDevDataEntity;
import com.pig4cloud.pig.iotData.entity.IotDataKgnpkDevDataInfoEntity;
import com.pig4cloud.pig.iotData.mapper.IotDataKgnpkDevDataInfoMapper;
import com.pig4cloud.pig.iotData.mapper.IotDataKgnpkDevDataMapper;
import com.pig4cloud.pig.iotData.service.IotDataKgnpkDevDataService;
import com.pig4cloud.plugin.websocket.config.WebSocketMessageSender;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * kg突然检测NPK实时存储的数据
 *
 * @author lty
 * @date 2024-11-18 22:37:28
 */
@Slf4j
@Service
public class IotDataKgnpkDevDataServiceImpl extends ServiceImpl<IotDataKgnpkDevDataMapper, IotDataKgnpkDevDataEntity> implements IotDataKgnpkDevDataService {

	@Resource
	private IotDataKgnpkDevDataInfoMapper iotDataKgnpkDevDataInfoMapper;
	private final List<AbnormalIndicator> abnormalIndicators = new ArrayList<>();
	@Resource
	private IotDeviceMessageService iotDeviceMessageService;
	@Override
	public List<DuorouKgnpkDevDataInfoDto> getDataInfDtoListByDataIdAndMeasureName(List<Long> dataIdList, String measureName) {
		return iotDataKgnpkDevDataInfoMapper.getDataInfDtoListByDataIdAndMeasureName(dataIdList,measureName);
	}

	@Override
	public List<AbnormalIndicator> getAbnormalIndicators(Long entityId) {
		// 这里可以根据 entityId 做更精细的过滤，示例中简单返回所有异常指标
		return abnormalIndicators;
	}

	/**
	 * 解析测量范围字符串（增强容错性）
	 * 支持格式示例：
	 * - "－30～70℃"
	 * - "0～1999mg/kg（mg/L）"
	 * - "30～80%"
	 */
	private Range parseMeasureRange(String rangeStr) {
		try {
			// 处理全角符号（U+FF0D）
			String cleanStr = rangeStr.replaceAll("（.*?）", "")
					.replaceAll("[^0-9.－～-]", "");
			cleanStr = cleanStr.replace("－", "-")   // 全角短横线
					.replace("～", "-");  // 全角波浪线

			String[] parts = cleanStr.split("-");
			if (parts.length != 2) {
				log.error("无效的范围格式: {}");
				return new Range(Float.MIN_VALUE, Float.MAX_VALUE);
			}

			float min = parseNumber(parts[0]);
			float max = parseNumber(parts[1]);
			return new Range(min, max);
		} catch (Exception e) {
			log.error("范围解析失败 | 原始字符串: {} | 错误: {}");
			return new Range(Float.MIN_VALUE, Float.MAX_VALUE);
		}
	}

	@Override
	public void checkAllMeasures(IotDataKgnpkDevDataEntity entity) {
		// 清空旧的异常记录
		abnormalIndicators.clear();

		// 查询详细数据
		List<IotDataKgnpkDevDataInfoEntity> infoList = iotDataKgnpkDevDataInfoMapper.selectList(
				Wrappers.lambdaQuery(IotDataKgnpkDevDataInfoEntity.class)
						.eq(IotDataKgnpkDevDataInfoEntity::getKgnpkDevDataId, entity.getId())
		);

		// 检测每个指标
		infoList.forEach(info -> {
			String measureName = info.getMeasureName();
			Double actualValue = info.getMeasureValue();
			String measureRange = info.getMeasureRange();
			Range range = parseMeasureRange(measureRange);

			if (actualValue < range.getMin() || actualValue > range.getMax()) {
				// 记录异常
				abnormalIndicators.add(new AbnormalIndicator(measureName, actualValue, measureRange));
				// 插入报警记录
				createAlarm(entity, measureName, actualValue.floatValue(), measureRange);
			}
		});
	}
	private float parseNumber(String str) {
		// 处理科学计数法（如1e3）和特殊符号
		return Float.parseFloat(str.replaceAll("[^0-9.Ee-]", ""));
	}

	private void createAlarm(IotDataKgnpkDevDataEntity dataEntity, String measureName,
							 float actualValue, String measureRange) {
		IotDeviceMessageEntity alarm = new IotDeviceMessageEntity();
		alarm.setDevId(dataEntity.getIotDeviceId()); // 对应 dev_id
		alarm.setMessageType(measureName + "_ALARM");
		alarm.setMessageDescribe(String.format(
				"[%s]异常！当前值: %s，允许范围: %s",
				measureName,
				formatValue(actualValue, measureName),
				measureRange
		));
		alarm.setMessageSpecialInfo("{bucketName=local, fileName=alarm.jpeg, url=/admin/duorouKgbotcamFile/local/duorouKgBotCamDet/2025/03/30/detected/alarm.jpg}");
		alarm.setMessageStatement("0");
		alarm.setCreateBy("system_monitor");
		alarm.setUpdateBy("system_monitor");
		alarm.setCreateTime(LocalDateTime.now());
		alarm.setUpdateTime(LocalDateTime.now());
		alarm.setDelFlag("0");

		sendWebSocketAlarm(alarm);

		iotDeviceMessageService.save(alarm);
	}


	// ================= WebSocket报警发送方法 =================
	private void sendWebSocketAlarm(IotDeviceMessageEntity alarm){
		try {
			// 1. 构建精简的消息内容（仅含 messageType 和 devId）

			Map<String, Object> alarmMsg = new HashMap<>();
			alarmMsg.put("messageType", alarm.getMessageType());
			alarmMsg.put("devId", alarm.getDevId());
			alarmMsg.put("messageDescribe", alarm.getMessageDescribe());
			alarmMsg.put("messageSpecialInfo", alarm.getMessageSpecialInfo());

			log.info(alarm.toString());


			// 2. 将消息转换为JSON字符串
			ObjectMapper mapper = new ObjectMapper();
			String jsonMessage = mapper.writeValueAsString(alarmMsg);

			// 3. 通过WebSocket发送（使用原始send方法）
			WebSocketMessageSender.send("admin", jsonMessage);

			log.debug("WebSocket报警已发送 | 设备ID: {}", alarm.getDevId());
		} catch (Exception e) {
			log.error("WebSocket发送失败 | 设备ID: {} | 错误: {}",
					alarm.getDevId(), e.getMessage());
		}
	}

	/**
	 * 根据测量类型格式化数值
	 */
	private String formatValue(float value, String measureName) {
		return switch (measureName) {
			case "土壤温度", "空气温度" -> String.format("%.1f℃", value);
			case "土壤容积含水率", "空气湿度" -> String.format("%.1f%%", value);
			case "土壤电导率" -> String.format("%dμS/cm", (int) value);
			case "土壤含氮量", "土壤含磷量", "土壤含钾量" -> String.format("%dmg/kg", (int) value);
			case "光照" -> String.format("%dlux", (int) value);
			case "二氧化碳" -> String.format("%dppm", (int) value);
			default -> String.format("%.2f", value);//土壤ph值
		};
	}

	// 范围值对象
	@Getter
	@AllArgsConstructor
	private static class Range {
		private float min;
		private float max;
	}
}